#include <stdlib.h>
#include <string.h>
#include "manipulations.h"
#include "status.h"

Status compare(ElemType a, ElemType b){
    if(a.value == b.value)
        return EQUAL;
    return UNEQUAL;
}

Status IncreaceList(SqList *L){
    if((L->length + 1) >= L->listsize){
        SqList *tmp;
        tmp = realloc(L, L->listsize + LISTINCREMENT);
        if(tmp == NULL){
            return FAILED;
        }
        return OK;
    }
    return OK;
}

Status InitList_Sq(SqList *L){
    L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));

    if (!L->elem) {
        exit(OVERFLOW);
    }

    L->length = 0;
    L->listsize = LIST_INIT_SIZE;
    return OK;
}

int GetElem_Sq(SqList L, int i, ElemType *e){
    /*判断 i 是否在 L.length 范围外*/
    if(i < 1 || i > L.length)
        return OUTOFBOUND;

    ElemType elem = *(L.elem + (i-1));
    e = (ElemType *)malloc(sizeof(ElemType));
    memcpy(e, &elem, sizeof(ElemType));
    if(e == NULL)
        return FAILED;
    return SUCCESS;

}

Status ListInsert_Sq(SqList *L, int i, ElemType e){
    //判断 i 是否在 L.length 范围外
    if(i < 1 || i >= L->length)
        return OUTOFBOUND;

    //判断当前容量是否已经不足
    if((L->length + 1) >= L->listsize){
        if (IncreaceList(L) != OK){
            return FAILED;
        }
    }

    for(int j = L->length; j > (i-1); j++){
        *(L->elem + j) = *(L->elem + (j-1));
    }
    *(L->elem + (i-1)) = e;
    L->length += 1;
    return OK;
}

Status ListDelete_Sq(SqList *L, int i, ElemType *e){
    //判断 i 是否在 L.length 范围外
    if(i < 1 || i >= L->length)
        return OUTOFBOUND;

    e = (ElemType *)malloc(sizeof(ElemType));
    if(e == NULL){
        return OVERFLOW;
    }
    *e = *(L->elem + (i-1));

    for(int j=(i-1); j<L->length; j++){
        *(L->elem + j) = *(L->elem + (j+1));
    }
    L->length -= 1;
    return OK;
}

int LocatElem_Sq(SqList L, ElemType e, Status (*compare)(ElemType, ElemType)){
    for(int i=0; i<L.length; i++){
        if(compare(e, *(L.elem + i)) == EQUAL){
            return i + 1;
        }
    }
    return 0;
}

void MergeList_Sq(SqList La, SqList Lb, SqList *Lc){
    InitList_Sq(Lc);
    //判断 Lc 的容量是否足够
    while(Lc->listsize <= (La.length + Lb.length)){
        if(IncreaceList(Lc))
            exit(FAILED);
    }

    int i = 0;
    for(i=0; i < La.length; i++){
        *(Lc->elem + i ) = *(La.elem + i);
    }

    for (int j = 0; j < Lb.length; j++){
        *(Lc->elem + j + i) = *(Lb.elem + j);
    }

    Lc->length = La.length + Lb.length;
}

Status SubList_Sq(SqList *La, const SqList *Lb){
    ElemType tmp_e;
    if(La->length < Lb->length){
        return FAILED;
    }
    for (int i = 0; i < Lb->length; ++i) {
        int index = LocatElem_Sq(*La, *(Lb->elem + i), compare);
        if(index != 0){
            if(ListDelete_Sq(La, index, &tmp_e) != OK)
                return FAILED;
        }
    }
    return OK;
}

Status AppendList_Sq(SqList *L, ElemType e){
    int i = L->length + 1;
    ListInsert_Sq(L, i, e);
}

void DestryList_Sq(SqList *L){
    free(L->elem);
    free(L);
}
